/**
 * Created by yanghaijin on 2018/2/8.
 */
class CardController{
    static getInstance(){
        if (!CardController._instance) {
            CardController._instance = new CardController();
        }
        return CardController._instance;
    }
    constructor(){
    }
    /*
    * 洗牌、发牌
    * */
    shuffle(players){
        // 1、抽牌法
        let shuffle_pick = function (m) {
            //生成m张牌
            let arr = new Array(m);
            for (let i = 0; i < m; i++) {
                arr[i] = i;
            }
            //每次抽出一张牌，放在另一堆。把最后一张未抽的牌放在空位子上。
            let cards = [];
            for (let i = m; i > 0;) {
                let rnd = Math.floor(Math.random() * i);
                cards.push(arr[rnd]);
                arr[rnd] = arr[--i];
            }
            return cards;
        };

        // 2、插牌法
        let shuffle_insert = function (m) {
            //每次生成一张最大的牌，与随机的某张牌换位子
            let arr = new Array(m);
            arr[0] = 0;
            for (let i = 1; i < m; i++) {
                let rnd = Math.floor(Math.random() * (i + 1));
                arr[i] = arr[rnd];
                arr[rnd] = i;
            }
            return arr;
        };

        // 3、换牌法
        let shuffle_swap = function (m) {
            //生成m张牌
            let arr = new Array(m);
            for (let i = 0; i < m; i++) {
                arr[i] = i;
            }
            //第i张与任意一张牌换位子，换完一轮即可
            for (let i = 0; i < m; i++) {
                let rnd = Math.floor(Math.random() * (i + 1)),
                    temp = arr[rnd];
                arr[rnd] = arr[i];
                arr[i] = temp;
            }
            return arr;
        };

        let shuffleCards = shuffle_pick(52);
        for (let i = 0; i < players.length; i++){
            let cards = [];
            for (let j = 0; j < 3; j++){
                cards.push(shuffleCards.shift());
            }
            let player = players[i];
            player.setCards(cards);
        }
    }
    pkCards(cardList1, cardList2){
        let Card = function (id) {
            let color = Math.floor(id / 13);
            let value = id % 13;
            return {
                color: color,
                value: value,
                sort: 13 - value,
                des: ["黑桃", "红桃", "梅花", "方块"][color] + ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"][value]
            }
        };
        let isDouble = function(cardList) {
            let map = {};
            for (let i = 0; i < cardList.length; i++) {
                let value = cardList[i].value;
                map[value] = true;
            }
            if (Object.keys(map).length === 2) {
                return true;
            }
            return false;
        };
        let isChain = function(cardList) {
            let values = [];
            for (let i = 0; i < cardList.length; i++) {
                values.push(cardList[i].value);
            }
            values.sort(function (a, b) {
                return a - b;
            });
            if (values[0] + 1 === values[1] && values[1] + 1 === values[2]) {
                return true;
            }
            return false;
        };
        let isSameColor = function(cardList){
            let map = {};
            for(let i = 0; i < cardList.length; i++){
                map[cardList[i].color] = true;
            }
            return Object.keys(map).length === 1;
        };
        let isSameColorChain = function(cardList) {
            if (isSameColor(cardList) && isChain(cardList)) {
                return true;
            }
            return false;
        };
        let isBoss = function(cardList){
            let map = {};
            for(let i = 0; i < cardList.length; i++){
                map[cardList[i].value] = true;
            }
            return Object.keys(map).length === 1;
        };
        for (let i = 0; i < 3; i++){
            cardList1[i] = Card(cardList1[i]);
            cardList2[i] = Card(cardList2[i]);
        }
        let checkFuntion = {
            isDouble: isDouble,
            isChain: isChain,
            isSameColor: isSameColor,
            isSameColorChain: isSameColorChain,
            isBoss: isBoss
        };
        let CardType = {
            Single: 0,
            Double: 1,
            Chain: 2,
            SameColor: 3,
            SameColorChain: 4,
            Boss: 5
        };
        let checkResult = {
            isSingle: CardType.Single,
            isDouble: CardType.Double,
            isChain: CardType.Chain,
            isSameColor: CardType.SameColor,
            isSameColorChain: CardType.SameColorChain,
            isBoss: CardType.Boss
        };
        let sortCard = function (cards) {
            if (isDouble(cards)) {
                let map = {};
                for (let i = 0; i < cards.length; i++) {
                    let card = cards[i];
                    if (map.hasOwnProperty(card.value)) {
                        map[card.value].push(card);
                    } else {
                        map[card.value] = [card];
                    }
                }
                let singleValue = 0;
                for (let value in map) {
                    if (map[value].length === 1) {
                        singleValue = parseInt(value);
                    }
                }
                cards.sort(function (a, b) {
                    return a.value === singleValue;
                });
            } else {
                cards.sort(function (a, b) {
                    return a.value > b.value;
                });
            }
            return cards;
        };
        let result = { 0: CardType.Single, 1: CardType.Single };
        let getResult = function (cardList1, cardList2) {
            let cards = [cardList1, cardList2];
            for (let i = 0; i < 2; i++) {
                for (let key in checkFuntion) {
                    if (checkFuntion[key](cards[i])) {
                        result[i] = checkResult[key];
                    }
                }
            }
            cardList1 = sortCard(cardList1);
            cardList2 = sortCard(cardList2);
            if (result[0] === result[1]) {
                switch (result[0]) {
                    case CardType.Single:
                        // 单牌只比较牌面值(value)，不比较花色(color)
                        return cardList1[2].value > cardList2[2].value;
                        break;
                    case CardType.Double:
                        // 先比对子牌、再比单牌
                        if (cardList1[0].value === cardList2[0].value) {
                            return cardList1[2] > cardList2[2];
                        }
                        return cardList1[0].value > cardList2[0].value;
                        break;
                    case CardType.Chain:
                        // 只比最大或最小的牌
                        if (cardList1[0].value === cardList2[0].value) {
                            return cardList1[2].color < cardList2[2].color;
                        }
                        return cardList1[0].value > cardList2[0].value;
                        break;
                    case CardType.SameColor:
                        if (cardList1[0].color === cardList2[0].color) {
                            return cardList1[0].value > cardList2[0].value;
                        }
                        return cardList1[0].color < cardList2[0].color;
                        break;
                    case CardType.SameColorChain:
                        return cardList1[0].value < cardList2[0].value;
                        break;
                    case CardType.Boss:
                        return cardList1[0].value > cardList2[0].value;
                        break;
                    default:
                        break;
                }
            }
            return result[0] > result[1];
        };
        let pkResult = {};
        pkResult.card_type = result;
        pkResult.iswin = getResult(cardList1, cardList2);
        return pkResult;
    }
}
CardController._instance = null;
module.exports = CardController;